package com.codingday.app;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;


// Run in Background
// get current location from gps data
// compare with todo's location
// 
public class GeoAlarmService extends Service implements LocationListener{

	
	
		private int NOTIFICATION = R.string.local_service_started;
	 	private NotificationManager mNM;
	
	 	private static GeoAlarmService instance = null;
	 	
		private static final int gpsMinTime = 60000;
	    private static final int gpsMinDistance = 5;

	    private LocationManager manager = null;
	    private static double latitude = 0.0;
	    private static double longitude = 0.0;
	    //private double altitude = 0.0;
	    
	    private Timer monitoringTimer = null;
	    private Criteria criteria = null;
	    
	    
	    private final IBinder mBinder = new GeoAlarmBinder();
	    public class GeoAlarmBinder extends Binder{
	    	GeoAlarmService getService(){
	    		return GeoAlarmService.this;
	    	}
	    }
	
		public GeoAlarmService() {
			Log.i("GeoAlarmService","GPSLoggerService.GPSLoggerService().");
		}

		@Override
		public IBinder onBind(Intent intent) {
			Log.i("GeoAlarmService","GPSLoggerService.onBind().");
			// return mBinder
			return mBinder;
		}

		public static boolean isInstanceCreated() { 
		      return instance != null; 
		}
		
		@Override
		public void onCreate() {
			Log.i("GeoAlarmService","GPSLoggerService.onCreate().");
			instance = this;
			mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);



			super.onCreate();
		}

		@Override
		public void onDestroy() {
			// TODO Auto-generated method stub
			super.onDestroy();
			instance = null;
			Toast.makeText(getApplicationContext(), "GeoAlarm Service Stop", 1).show();
			 mNM.cancel(NOTIFICATION);
			 stopLoggingService();
			 
		}

		// onStart for old api
		// onStartCommand for new api
		@Override
		public void onStart(Intent intent, int startId) {
			Log.i("GeoAlarmService","GPSLoggerService.onStart().");

			startLoggingService();
            startMonitoringTimer();
			super.onStart(intent, startId);
		}

		public int onStartCommand(Intent intent, int flags, int startId) {
			Log.i("GeoAlarmService","GPSLoggerService.onStartCommand().");

			startLoggingService();
            startMonitoringTimer();
			return Service.START_STICKY;
		}

		
		// Notify
		private void showNotification(ArrayList<Integer> todoIDArray){
			CharSequence text = "Notification Test";
			// show notification now
			Notification notification = new Notification(R.drawable.icon, text, System.currentTimeMillis());
			Intent intent = new Intent(this,TODONowList.class);
			intent.putExtra("positions", todoIDArray);
			intent.putExtra("fromNotification", true);
			//Log.i("Show Notification", "position : "+positionArray);
			PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
			//contentIntent.
			notification.flags = Notification.FLAG_AUTO_CANCEL;
			notification.setLatestEventInfo(this, "", text, contentIntent);
			
			// add sound, vibration and light
			notification.defaults |= Notification.DEFAULT_SOUND;
			notification.defaults |= Notification.DEFAULT_VIBRATE;
			//notification.defaults |= Notification.DEFAULT_LIGHTS;
			
			// send notify
			mNM.notify(NOTIFICATION, notification);
		}
		
		
		// Implement LocationListener
		@Override
		public void onLocationChanged(Location location) {
			// TODO Auto-generated method stub
			
			Log.i("GeoAlarmService","Location Changed:"+location.getLatitude()+","+location.getLongitude());
			
			double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            //altitude = location.getAltitude();
            GeoAlarmService.latitude = location.getLatitude();
            GeoAlarmService.longitude = location.getLongitude();
            MyLocationManager.getInstance(getApplicationContext()).setLocation(latitude, longitude);
		
		}
		
		
		


		@Override
		public void onProviderDisabled(String arg0) {
			// TODO Auto-generated method stub
		}

		@Override
		public void onProviderEnabled(String provider) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub
			
		}
		
		
		private void startLoggingService(){
			if(manager == null)
            {
                    manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            }

            String bestProvider = initBestProvider();
 
            
            Location location = null;
            if (bestProvider != null && bestProvider.length() > 0)
            {
                    manager.requestLocationUpdates(bestProvider, gpsMinTime, gpsMinDistance, this);
                    location = manager.getLastKnownLocation(bestProvider);
            }
            else
            {
                    final List<String> providers = manager.getProviders(true);
                    
                    for (final String provider : providers)
                    {
                            manager.requestLocationUpdates(provider, gpsMinTime, gpsMinDistance, this);
                            location = manager.getLastKnownLocation(provider);
                    }
            }

			if(location == null){
				
			}else{
				// update initial position
				double latitude = location.getLatitude();
	            double longitude = location.getLongitude();
	            //altitude = location.getAltitude();
	            GeoAlarmService.latitude = location.getLatitude();
	            GeoAlarmService.longitude = location.getLongitude();
	            MyLocationManager.getInstance(getApplicationContext()).setLocation(latitude, longitude);
			}
			
		}
		private void initCriteria(){
			criteria = new Criteria();
            criteria.setAccuracy(Criteria.ACCURACY_FINE);
            criteria.setAltitudeRequired(false);
            criteria.setBearingRequired(false);
            criteria.setCostAllowed(true);
            criteria.setPowerRequirement(Criteria.POWER_LOW);
		}
		
		private String initBestProvider(){
			if(criteria == null){
				initCriteria();
			}
            final String bestProvider = manager.getBestProvider(criteria, true);
            return bestProvider;
		}

		
		private void stopLoggingService(){
            stopSelf();
		}
		
		private void CheckTODOs(){
			ArrayList<TODO> todolist = TODOListManager.getTODOList();
			Log.i("GeoAlarmService","TimerTask Run, todolistSize : " + todolist.size());
			
			if(MyLocationManager.getInstance(getApplicationContext()).getLatitude() == 0.0 && MyLocationManager.getInstance(getApplicationContext()).getLongitude() == 0.0){
				Log.i("GeoAlarmService","Both Latitud and Longitude are 0");
				return;
			}
			
			ArrayList<Integer> todoIDArray = new ArrayList<Integer>();
			int minDistance = -1;
			for(int i = 0; i < todolist.size(); i++){
				
				TODO todo = todolist.get(i);
				if(todo.isEnabled() == false){
					continue;
				}
				if(todo.isCompleted() == true){
					continue;
				}
				
				double todoLatitude = todo.getLatitude();
				double todoLongitude = todo.getLongitude();
				int radius = todo.getRadius();
				Log.i("GeoAlarmService","current : "+latitude+","+longitude);
				Log.i("GeoAlarmService","todo : "+todoLatitude+","+todoLongitude);
				float distance = MyLocationManager.getInstance(getApplicationContext()).getDistanceTo(todoLatitude, todoLongitude);
				
				Log.i("GeoAlarmService","distance : "+distance+"m");
				if(distance <= radius){
					if(todo.isPausedByInitial()){
						continue;
					}
					Log.i("GeoAlarmService","You are now neer : "+todo.getTitle());
					todoIDArray.add(new Integer((int) todo.getID()));
					todo.resumeFromInitialPause(false);
				}else{
					if(todo.isPausedByInitial()){
						todo.resumeFromInitialPause(true);
					}
				}
			}
			
			if(todoIDArray.size() > 0){
				showNotification(todoIDArray);
			}
			if(minDistance != -1){
				// here is mindistance
				// calibrate updateTime
			}
		}
		
		private void startMonitoringTimer(){
			monitoringTimer = new Timer();
			Toast.makeText(getApplicationContext(), "Start Geo Alarm Service - Monitoring Timer", 1).show();
			
			monitoringTimer.scheduleAtFixedRate(
					new TimerTask(){

						@Override
						public void run() {
							CheckTODOs();
						}
						
					}
					,GeoAlarmSetting.getInstance(getApplicationContext()).getServiceUpdateTime()
					//, GeoAlarmService.TIMER_DELAY
					, GeoAlarmSetting.getInstance(getApplicationContext()).getServiceUpdateTime()
			);
			
			
		}
		

}
